/*********************************** (C) COPYRIGHT ******************************
 * address: https://gitee.com/liuniansihuo/multitasks-os
 *
 * Change Logs:
 * Date			Author      	Notes
 * 2019-06-16	LiuHuo			first version
 *
*******************************************************************************/
#include "fifo.h"


unsigned char fifo_is_full(const struct FIFO_S * Q)
{
	return ((Q->tail + 1)%Q->size) == Q->head;
}

unsigned char fifo_is_empty(const struct FIFO_S * Q)
{
	return Q->tail == Q->head;
}
unsigned int fifo_get_length(const struct FIFO_S * Q)
{
	return (Q->size + Q->tail - Q->head) % Q->size;
}

unsigned int fifo_free_length(const struct FIFO_S * Q)
{
	return (Q->size + Q->head - Q->tail - 1) % Q->size;
}

unsigned char fifo_get_data(const struct FIFO_S * Q,unsigned int offset)
{
	return Q->buff[ (Q->head+offset)%Q->size ];
}
unsigned int fifo_get_datas(struct FIFO_S * Q,unsigned char * buff)
{
	unsigned int offset=0;

	offset = (Q->size + Q->tail - Q->head) % Q->size;
	for(int i=0; i<offset; i++)
	{
		buff[i] = Q->buff[ (Q->head+i)%Q->size ];
	}
	Q->head = (Q->head + offset)%Q->size;
	return offset;
}

void fifo_discard_one(struct FIFO_S * Q)
{
	Q->head = (Q->head + 1)%Q->size;
}
void fifo_head_offset(struct FIFO_S * Q, unsigned int offset)
{
	Q->head = (Q->head + offset)%Q->size;
}

unsigned int fifo_set_data(struct FIFO_S * Q,const unsigned char * buff,unsigned int len)
{
	unsigned int  i=0;

	for(i=0; i<len; i++)
	{
		if(fifo_is_full(Q))
			break;

		Q->buff[Q->tail] = buff[i];
		Q->tail++;
		Q->tail%=Q->size;
	}

	return i;
}

unsigned int fifo_get_length_continue(const struct FIFO_S * Q)
{
    return (Q->head<=Q->tail) ? (Q->tail-Q->head) : (Q->size - Q->head);
}

unsigned char * fifo_get_head_addr(const struct FIFO_S * Q)
{
	return (Q->buff+Q->head);
}
unsigned int fifo_get_size(const struct FIFO_S * Q)
{
	return Q->size;
}

void fifo_tail_set(struct FIFO_S * Q,unsigned int tail)
{
	Q->tail = tail%Q->size;
}



